import g

import asyncio
from lib.myprocess import MyProcess
from server.rpc.rpcmanage import RpcManage
from server.rpc import DiscoverOption
from server import RedisDiscoverService
import uvicorn
from fastapi import FastAPI
from typing import Optional, Any
import time

Name = "gateway"
Address = ""

"""网关"""
app = FastAPI()


@app.on_event("startup")
async def startup():
    set_address(g.rpcManage.address)

    # rpc调度服务器启动
    await g.rpcManage.run()

    # 注册服务
    await register_service(get_address(), int(time.time()))


@app.on_event("shutdown")
async def shutdown():
    # 销毁服务
    await remove_service()


def get_address():
    """获取当前网关地址"""
    return Address


def set_address(address):
    """设置网关地址"""
    global Address
    Address = address


async def register_service(field: str, val: Any):
    """注册gateway服务"""
    await g.redis.hset(Name, field, val)


async def remove_service(field: Optional[str] = None):
    """注销gateway服务"""
    if field is None:
        field = get_address()

    if not field:
        return

    await g.redis.hdel(Name, field)


async def get_all_service():
    """获取所有gateway服务"""
    return await g.redis.hgetall(Name)


def init_route():
    """初始化路由"""

    import importlib
    for route_file in [
        "ws_route",
        "http_route",
    ]:
        importlib.import_module(f"gateway.{route_file}").init_route()


def _run(ip, port):
    g.init()
    init_route()
    # 服务发现配置
    discover_option = DiscoverOption(
        node_name=f"worker",
        instance=RedisDiscoverService(g.redis),
    )

    # rpc调度器
    g.rpcManage = RpcManage(ip, port, discover_option, name=Name)

    # 服务启动
    uvicorn.run(
        "gateway:app",
        host=ip,
        port=port,
        log_level="critical"
    )


def run(ip, port, is_print=True):
    if is_print:
        print(f"启动子进程服务 {Name}_{ip}:{port}")

    _run(ip, port)


def process_run(ip, port):
    process = MyProcess(f"{Name}_{ip}:{port}", run, ip, port, is_print=False)
    process.start()

    return process


if __name__ == '__main__':
    run("10.0.0.153", 8001)
